# Copyright (c) Injasuti Consulting Limited. All rights reserved.
# THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
# Description: This script performs site collection backups of all site collections in a SharePoint farm.
# Platform   : Tested on the following platforms - Windows Server 2008, Windows Server 2008 R2, SharePoint Server 2010
# Example    : .\FarmSitesBackup.ps1 -farmConfigFileName "c:\temp\Farm.xml" -backupFolder "c:\Backups\ICSS" -smtpMailConfigFileName "c:\install\spspareparts\ps-backup\SMTPMailConfig-IC.xml"
#
# TODO: Implement standard headers
# TODO: Implement validation
# TODO: Implement daysHistoryToKeep parameter
# TODO: Implement backupSites switch
# TODO: Implement backupDatabases switch
# TODO: Implement compressDatabases switch
# TODO: Implement sendMail switch
# TODO: Implement whatIf switch
#
# ========================================

# PARAMETERS
# ========================================
param([string] $farmConfigFileName, [string] $backupFolder, [string] $smtpMailConfigFileName, [int] $daysHistoryToKeep, [switch] $backupSites, [switch] $backupDatabases, [switch] $compressDatabases, [switch] $sendMail, [switch] $whatIf, [switch] $nocls)

# GLOBAL VARIABLES
# ========================================
#$ErrorActionPreference = "Stop"

# LOAD ASSEMBLIES
# ========================================

# EXTERNAL FUNCTIONS
# ========================================

# FUNCTIONS
# ========================================

function create-folder ([string]$folderName)
{
  # Create subfolder for the backups
  if ((Test-Path -path $folderName) -ne $True)
  {
  	Write-Host "Creating  : " $folderName -ForegroundColor DarkCyan -BackgroundColor White
  	New-Item $folderName -type directory
  }
}

function remove-history ([string]$folderName, [int]$historyRetainDays)
{
 	#Clean up files 
 	[datetime] $fileArchiveDateCutoff = $todaysDate.AddDays(-$historyRetainDays)
 	Write-Host "Deleting files older than " $fileArchiveDateCutoff " in " $folderName -ForegroundColor DarkCyan -BackgroundColor White
 	
 	$files = Get-ChildItem $folderName -include *.* -recurse
 	foreach ($file in $files) 
 	{
 	  if ($file -ne $null)
 	  {
   	  [datetime] $lrt = $file.LastWriteTime
   	  [string] $f = $file
    	Write-Host "Checking file " $f " " $lrt -ForegroundColor DarkCyan -BackgroundColor White
   	  if ($lrt -lt $fileArchiveDateCutoff)
   	  {
   	  	Write-Host "Deleting file " $f -ForegroundColor DarkCyan -BackgroundColor White
   	  	Remove-Item $file
   	  }
 	  }
 	} 
}

function remove-empty-folders([string]$folderName)
{
  $x = (Get-ChildItem $folderName -recurse | Where-Object {$_.PSIsContainer -eq $True}) | Where-Object {$_.GetFiles().Count -eq 0 -and $_.GetDirectories().Count -eq 0} | Select-Object FullName  
  foreach ($d in $x)
  {
    $y = $d.FullName
    if ([System.String]::IsNullOrEmpty($y) -eq $FALSE)
    {
      Write-Host "Removing folder " $d.FullName
      Remove-Item $d.FullName
    }
  }
}

# MAIN
# ========================================

if ($nocls -eq $false) { CLS }

# ========================================

$transcriptFile = $backupFolder + "\WSSGenericBackup.results.txt"

Write-Host 
Write-Host $farmConfigFileName		 -BackgroundColor Blue -ForegroundColor Yellow
Write-Host $backupFolder			     -BackgroundColor Blue -ForegroundColor Yellow
Write-Host $smtpMailConfigFileName -BackgroundColor Blue -ForegroundColor Yellow
Write-Host 

# ========================================

$whatIfMode = $false

# ========================================

Create-Folder $backupFolder

Start-Transcript -Path $transcriptFile -Force 

[string] $sqlBackupFileName = Get-Location
$sqlBackupFileName = $sqlBackupFileName + "..\SQL\wssdatabasemaintenance.sql"

$farmConfigXml = [xml]$(get-content $farmConfigFileName)

[datetime] $todaysDate   = Get-Date -hour 00 -minute 00 -second 00
[string]   $todaysFolder = $todaysDate.ToString("yyyyMMdd")
[string]   $todaysDay    = ("{0:ddd}" -f $todaysDate).ToUpper()

$attachmentsList = new-Object System.Collections.ArrayList

# Days history to keep
[int] $daysHistory = 365

$processStartDateTimeString = Get-Date -format "yyyyMMdd-HHmmss"
Write-Host "Starting ..." $processStartDateTimeString  -ForegroundColor White -BackgroundColor DarkCyan

# Process farm
foreach ($Service in $farmConfigXml.Farm.Services.Service)
{
  # Process web applications
  foreach ($WebApplication in $Service.WebApplications.WebApplication)
  {
    if ($WebApplication -ne $null)
    {
      Write-Host " "
      Write-Host "Processing web application -" $WebApplication.Name
      $waname = $WebApplication.Name

      # Process databases
      foreach ($Database in $WebApplication.Databases.Database)
      {
        if ($Database -ne $null)
        {
          $databasename = $Database.DatabaseName
          Write-Host "Processing database -" $databasename
  
        }
      }
    
      # Process site collections
      foreach ($SiteCollection in $WebApplication.SiteCollections.SiteCollection)
      {
        if ($SiteCollection -ne $null)
        {
          Write-Host "Processing site collection -" $SiteCollection.Url
    
          # Perform site collection backup
          $scport                     = $SiteCollection.Port
          $scurl                      = $SiteCollection.Url
          $scserverrelativeurl        = $SiteCollection.ServerRelativeUrl
          if ($scserverrelativeurl -eq "/") { $scserverrelativeurl = "root" }
          $scbackupfolder             = $backupFolder + "\" + $scport + "\" + $waname + "\" + $todaysFolder
          $scbackupfolder             = $scbackupfolder.Replace(" ", "-")

          $scbackupdatetime           = Get-Date -format "yyyyMMdd-HHmmss"
          $scbackupfile               = $scbackupfolder + "\" + $scserverrelativeurl + ".bak"
          $scbackupfile               = $scbackupfile.Replace("/", "\").Replace("\\", "\")
          $scoutputfile               = $scbackupfolder + "\" + $scserverrelativeurl + ".results.txt"
          $scoutputfile               = $scoutputfile.Replace("/", "\").Replace("\\", "\")

          # Create folder
          $scbackupfolderpath = Split-Path -Parent -Path $scbackupfile
          create-folder $scbackupfolderpath

          # Work out backup command
          $sccommand = "stsadm `-o backup `-overwrite `-url `"$scurl`" `-filename `"$scbackupfile`" > `"$scoutputfile`""
          Write-Host $sccommand -ForegroundColor White -BackgroundColor DarkCyan
          if (!$whatIfMode)
          {
            # Run backup command
            Invoke-Expression $sccommand
          }
        }
      }
    }
  }
}

Stop-Transcript

Write-Host ""
$processEndDateTimeString = Get-Date -format "yyyyMMdd-HHmmss"
Write-Host "Ending ..." $processEndDateTimeString  -ForegroundColor White -BackgroundColor DarkCyan

# END
# ========================================
